var util = require("util");

var playerCount = {};
var gamePlayerCount = {};

function handle(io, models) {
  io.sockets.on('connection', function (socket) {
    socket.on('set player', function (data) {
      playerCount[data.pk] = (playerCount[data.pk] || 0) + 1;
      socket.get('data', function(err, socketData) {
        socketData = socketData || {};
        socketData['pk'] = data.pk;
        socketData['name'] = data.name;
        socketData['remoteAvatar'] = data.remoteAvatar;
        socket.set('data', socketData);
        models.findEntityByPk(data.pk, models.Player, updatePlayerOnlineState,
            {online: true, socket: socket});
      });
    });
    
    socket.on('set game', function (data) {
      gamePlayerCount[data.gamePlayer] = (gamePlayerCount[data.gamePlayer] || 0) + 1;
      socket.get('data', function(err, socketData) {
        socketData = socketData || {};
        socketData['game'] = data.game;
        socketData['gamePlayer'] = data.gamePlayer;
        socket.set('data', socketData);
        
        models.findEntityByPk(data.gamePlayer, models.GamePlayer, function(err, gamePlayer) {
          if(!gamePlayer.online) {
            updatePlayerOnlineState(err, gamePlayer, {online: true, socket: socket});
            socket.broadcast.emit(util.format('chat message/%s', data.game), {
              text: "Joined game",
              sender: data.name,
              time: new Date().getTime(),
              remoteAvatar: data.remoteAvatar});
          }
        });
      });
    });
    
    socket.on('disconnect', function () {
      socket.get('data', function (err, socketData) {
        playerCount[socketData.pk]--;
        if (playerCount[socketData.pk] == 0) {
          models.findEntityByPk(socketData.pk, models.Player, updatePlayerOnlineState,
              {online: false, socket: socket});
        }
        if(socketData.gamePlayer) {
          gamePlayerCount[socketData.gamePlayer]--;
          if (gamePlayerCount[socketData.gamePlayer] == 0) {
            models.findEntityByPk(socketData.gamePlayer, models.GamePlayer, function(err, gamePlayer) {
              if(gamePlayer.online) {
                updatePlayerOnlineState(err, gamePlayer, {online: false, socket: socket});
                socket.broadcast.emit(util.format('chat message/%s', socketData.game), {
                  text: "Left game",
                  sender: socketData.name,
                  time: new Date().getTime(),
                  remoteAvatar: socketData.remoteAvatar});
              }
            });
          }
        }
      });
    });
  });
}

function updatePlayerOnlineState(err, player, args) {
  if (err || !player) {
    args.socket.disconnect();
    return;
  }
  player.online = args.online;
  player.setMetadata([{key: 'lastOnline', value: new Date()}], function() {
    player.save();
  });
}

exports.broadcastMessage = function(io, type, filter, data) {
  io.sockets.emit(util.format('%s/%s', type, filter), data);
};

exports.handle = handle;